package com.renan.util;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * java自带的xml解析工具类
 *
 * @author 张亚林
 */
public class JaxbUtil {

  /**
   * java对象转换为xml文件
   *
   * @param xmlPath xml文件路径
   * @param load java对象.Class
   * @return xml文件的String
   * @throws JAXBException
   */
  public static String beanToXml(Object obj, Class<?> load) throws JAXBException {
    JAXBContext context = JAXBContext.newInstance(load);
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
    StringWriter writer = new StringWriter();
    marshaller.marshal(obj, writer);
    return writer.toString();
  }

  /**
   * xml文件配置转换为对象
   *
   * @param xmlPath xml文件路径
   * @param load java对象.Class
   * @return java对象
   * @throws JAXBException
   * @throws IOException
   */
  @SuppressWarnings("unchecked")
  public static <T> T xmlToBean(String xmlPath, Class<T> load) throws JAXBException, IOException {
    JAXBContext context = JAXBContext.newInstance(load);
    Unmarshaller unmarshaller = context.createUnmarshaller();
    return (T) unmarshaller.unmarshal(new StringReader(xmlPath));
  }

  /**
   * JavaBean转换成xml 默认编码UTF-8
   *
   * @param obj
   * @param writer
   * @return
   */
  public static String convertToXml(Object obj) {
    return convertToXml(obj, "UTF-8");
  }

  /**
   * JavaBean转换成xml
   *
   * @param obj javabean对象
   * @param encoding 编码
   * @return 字符串
   */
  public static String convertToXml(Object obj, String encoding) {
    String result = null;
    try {
      JAXBContext context = JAXBContext.newInstance(obj.getClass());
      Marshaller marshaller = context.createMarshaller();
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
      // 去掉生成xml的默认报文头
      marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
      StringWriter writer = new StringWriter();
      writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n    ");
      marshaller.marshal(obj, writer);
      result = writer.toString();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  }

  /**
   * JavaBean转换成xml去除xml声明部分
   *
   * @param obj java 对象
   * @param encoding 字符串编码
   * @return 转换后的 xml
   */
  public static String convertToXmlIgnoreXmlHead(Object obj, String encoding) {
    String result = null;
    try {
      JAXBContext context = JAXBContext.newInstance(obj.getClass());
      Marshaller marshaller = context.createMarshaller();
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
      marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
      StringWriter writer = new StringWriter();
      marshaller.marshal(obj, writer);
      result = writer.toString();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  }

  /**
   * xml转换成JavaBean
   *
   * @param xml xml对象
   * @param c Class 对象
   * @return 转换后的实体
   */
  @SuppressWarnings("unchecked")
  public static <T> T converyToJavaBean(String xml, Class<T> c) {
    T t = null;
    try {
      JAXBContext context = JAXBContext.newInstance(c);
      Unmarshaller unmarshaller = context.createUnmarshaller();
      t = (T) unmarshaller.unmarshal(new StringReader(xml));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return t;
  }

  private static OutputFormat createPrettyPrint() {
    OutputFormat format = new OutputFormat();
    // format.setIndentSize(2);
    format.setNewLineAfterDeclaration(false);
    format.setNewlines(true);
    format.setTrimText(false);
    format.setPadText(false);
    return format;
  }

  /**
   * @Title: formatXml
   * @param str
   * @return
   * @throws Exception
   */
  public static String formatXml(String str) throws Exception {
    Document document = DocumentHelper.parseText(str);
    // 格式化输出格式
    OutputFormat format = createPrettyPrint();
    format.setEncoding("UTF-8");
    StringWriter writer = new StringWriter();
    // 格式化输出流
    XMLWriter xmlWriter = new XMLWriter(writer, format);
    // 将document写入到输出流
    xmlWriter.write(document);
    xmlWriter.close();
    return writer.toString();
  }
}
